package com.ww.springboot.boot.thread.study.base.lock.aqs.paint;

import com.ww.springboot.boot.baseTest.design.builder.Human;
import com.ww.springboot.boot.thread.study.base.lock.aqs.source.MyAbstractQueuedSynchronizer;

import javax.swing.*;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Optional;

/**
 * 描述：
 *
 * @author 🧑 ‍wanwei
 * @since 2023-03-18 14:18
 */
public class PaintAqs extends JFrame {

    private static MyAbstractQueuedSynchronizer myAQS = null;

    public PaintAqs(MyAbstractQueuedSynchronizer myAQS) throws HeadlessException {
        this.myAQS = myAQS;
        //添加组件
        add(new Composition());
    }

    public static void main(MyAbstractQueuedSynchronizer myAQS) {
        JFrame frame = new PaintAqs(myAQS);
        frame.setTitle("AQS");
        frame.setSize(1500, 1000);
        frame.setLocationRelativeTo(null);
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.setVisible(true);
    }


    static class Composition extends JPanel {

        //刷新重画
        public Composition() {
            Timer timer = new Timer(10, new Composition.Refresh());
            timer.start();
        }


        @Override
        protected void paintComponent(Graphics g) {
            super.paintComponent(g);
            g.setColor(Color.BLACK);
            g.setFont(new Font("宋体", Font.PLAIN, 20));

            MyAbstractQueuedSynchronizer.Node head = myAQS.getHead();
            MyAbstractQueuedSynchronizer.Node tail = myAQS.getTail();

            paintString(g, 450, 100, myAQS.getState());
            paintNode(g, 100, 100, myAQS.getHead(), "head");
            paintNode(g, 800, 100, myAQS.getTail(), "tail");

            MyAbstractQueuedSynchronizer.Node node = head;
            int i = 0;
            while (node != null) {
                paintNode(g, 100 + i * 120, 300, node, i);
                node = node.getNext();
                i++;
            }
        }

        class Refresh implements ActionListener {
            @Override
            public void actionPerformed(ActionEvent e) {
                //重画
                repaint();
            }
        }


        private void paintNode(Graphics g, int x, int y, MyAbstractQueuedSynchronizer.Node node, Object title) {
            if (node == null) {
                paintNode(g, title, x, y);
            } else {
                paintNode(g, title, x, y, node.getPrev(), node.getThread(), node.getNext(), node.getWaitStatus());
            }
        }

        private void paintNode(Graphics g, Object title, int x, int y, Object... text) {
            g.drawString(String.valueOf(title), x + 35, y - 10);
            g.drawRect(x, y, 100, 100);
            for (int i = 0; i < text.length; i++) {
                if (text[i] instanceof MyAbstractQueuedSynchronizer.Node) {
                    Thread thread = ((MyAbstractQueuedSynchronizer.Node) text[i]).getThread();
                    g.drawString(Optional.ofNullable(thread).map(Thread::getName).orElse("null"), x + 10, y + 20 + i * 20);
                } else if (text[i] instanceof Thread) {
                    g.drawString(String.valueOf(((Thread) text[i]).getName()), x + 10, y + 20 + i * 20);
                } else {
                    g.drawString(String.valueOf(text[i]), x + 10, y + 20 + i * 20);
                }

            }
        }

        private void paintString(Graphics g, int x, int y, Object text) {
            Font font = g.getFont();
            Color color = g.getColor();
            g.setColor(Color.RED);
            g.setFont(new Font("宋体", Font.PLAIN, 20));
            g.drawString(String.valueOf(text), x + 10, y - 10);
            g.setFont(font);
            g.setColor(color);
        }
    }


}
